package com.hwz.gulimaill.auth.web;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.hwz.common.constant.SmsConstant;
import com.hwz.common.entity.MemberEntity;
import com.hwz.common.entity.OAuthToken;
import com.hwz.common.exception.BizCodeEnume;
import com.hwz.common.utils.R;
import com.hwz.gulimaill.auth.fegin.MemberFeignService;
import com.hwz.gulimaill.auth.fegin.SmsFeignService;
import com.hwz.gulimaill.auth.vo.UserLoginVo;
import com.hwz.gulimaill.auth.vo.UserRegisterVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.session.Session;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.websocket.server.PathParam;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author: hwz
 * @CreateTime: 2025-10-19
 */

@Controller
@Slf4j
public class LoginController {

    @Resource
    SmsFeignService smsFeignService;

   @Autowired
    StringRedisTemplate redisTemplate;

    @Resource
    MemberFeignService memberFeignService;

    @GetMapping({ "/sms/sendCode"})
    @Transactional
    @ResponseBody
    public R sendCode(@PathParam("email") String email) {

        if(StringUtils.isEmpty(email)){
            return R.error(BizCodeEnume.PHONE_NUMBER_EMPTY.getCode(), BizCodeEnume.PHONE_NUMBER_EMPTY.getMsg());
        }

        //1、接口防刷
        String baseRedisCode = redisTemplate.opsForValue().get(SmsConstant.SMS_CODE_CACHE_PREFIX + email);
        if (!StringUtils.isEmpty(baseRedisCode)){
            String time = baseRedisCode.split("_")[1];
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis - Long.parseLong(time) < 60000){
                return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(), BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
            }
        }

        //2、验证码生成
        String code = UUID.randomUUID().toString().substring(0, 5);
        long currentTimeMillis = System.currentTimeMillis();
        String redisValue = code + "_" + currentTimeMillis;


        R r = smsFeignService.sendCode(email, code);
        if (r.getCode() == 0){
            //验证码放到redis
            String redisKey = SmsConstant.SMS_CODE_CACHE_PREFIX + email;
            redisTemplate.opsForValue().set(redisKey, redisValue, 5, TimeUnit.MINUTES);
            return R.ok();
        }else {
            return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(), (String) r.get("msg"));
        }
    }


    @PostMapping({ "/regist"})
    @Transactional
    public String register(@Valid @ModelAttribute UserRegisterVo userRegisterVo, BindingResult  result, RedirectAttributes redirectAttributes, Model model) {
        //1、数据校验
        if (result.hasErrors()){
            Map<String, String> errors = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage, (existing, newValue) -> existing)  );
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }

        //2、校验验证码
        String redisValue = redisTemplate.opsForValue().get(SmsConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getEmail());
        if (!StringUtils.isEmpty(redisValue) && redisValue.split("_")[0].equals(userRegisterVo.getCode())){
            //调用用户服务的注册功能
            redisTemplate.delete(SmsConstant.SMS_CODE_CACHE_PREFIX + userRegisterVo.getEmail());
            R r = memberFeignService.regist(userRegisterVo);
            if (r.getCode() == 0){
                return "login";
            }else {
                HashMap<String, String> errors = new HashMap<>();
                errors.put("msg", (String) r.get("msg"));
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.gulimall.com/reg.html";
            }

        }else {
            HashMap<String, String> errors = new HashMap<>();
            errors.put("code", "验证码错误");
            redirectAttributes.addFlashAttribute("errors", errors);
            return "redirect:http://auth.gulimall.com/reg.html";
        }
    }

    @PostMapping({ "/login"})
    @Transactional
    public String login(UserLoginVo userLoginVo, BindingResult  result, RedirectAttributes redirectAttributes, Model model, HttpSession session) {

            R r = memberFeignService.login(userLoginVo);
            if (r.getCode() == 0){
                MemberEntity member = (MemberEntity)r.getData(new TypeReference<MemberEntity>() {});
                session.setAttribute("loginUser", member);
                return "redirect:http://www.gulimall.com/";
            }else {
                HashMap<String, String> errors = new HashMap<>();
                errors.put("msg", (String) r.get("msg"));
                redirectAttributes.addFlashAttribute("errors", errors);
                return "redirect:http://auth.gulimall.com/login.html";
            }
    }


    @GetMapping({ "/auth2.0/gitee/success"})
    public String gitee(@RequestParam("code") String code, RedirectAttributes redirectAttributes, HttpSession session) {
        //1、用code去换取token
        String tokenUrl = "https://gitee.com/oauth/token?grant_type=authorization_code&code=" + code +
                "&client_id=c0682bb1e4eaac113b8bc9b6e893fc7eb59b21b74bbe6fdd84e9b78f3b769b81&redirect_uri=http://auth.gulimall.com/auth2.0/gitee/success&client_secret=2499e172437874af26fa372f2249b0258422631f39931bab6efb729af99499a2";

        HttpResponse response = HttpRequest.post(tokenUrl)
                .header("Content-Type", "application/json") // 可选：设置请求头
                .timeout(5000) // 可选：设置超时（毫秒）
                .execute();
        //2、实现登录操作（用户不存在就注册，存在就直接登录）
        if (response.getStatus() == 200){
            String body = response.body();
            OAuthToken oAuthTokenResponse = JSON.parseObject(body, OAuthToken.class);
            R r = memberFeignService.oauthLogin(oAuthTokenResponse);
            if (r.getCode() == 0){
                MemberEntity member = (MemberEntity)r.getData(new TypeReference<MemberEntity>() {});
                session.setAttribute("loginUser", member);
                return "redirect:http://www.gulimall.com/";
            }else {
                HashMap<String, String> map = new HashMap<>();
                map.put("msg", (String) r.get("msg"));
                redirectAttributes.addFlashAttribute("msg", map);
                return "redirect:http://auth.gulimall.com/login.html";
            }
        }else {
            log.error("获取accessToken失败");
            HashMap<String, String> map = new HashMap<>();
            map.put("msg", "获取accessToken失败");
            redirectAttributes.addFlashAttribute("msg", map);
            return "redirect:http://auth.gulimall.com/login.html";
        }

    }
}
